package com.kent.hellokotlin.cClassAndObject

//委托

//由委托实现
/*
委托模式已经证明是实现继承的一个很好的替代方式， 而 Kotlin 可以零样板代码地原生支持它。
Derived 类可以通过将其所有公有成员都委托给指定对象来实现一个接口 Base
*/
interface Base3 {
    fun print()
}

private fun foo() {
    class BaseImpl(val x: Int) : Base3 {
        override fun print() {
            println(x)
        }
    }

    class Derived3(b: Base3) : Base3 by b

    val b = BaseImpl(18)
    //Derived 的超类型列表中的 by-子句表示 b 将会在
    //Derived 中内部存储， 并且编译器将生成转发给 b 的所有 Base 的方法。
    Derived3(b).print()
}


//覆盖由委托实现的接口成员
interface Base4 {
    fun printMessage()
    fun printMessageLine()
}

private fun foo1() {
    class BaseImpl(val x: Int) : Base4 {
        override fun printMessage() {
            print(x)
        }

        override fun printMessageLine() {
            println(x)
        }
    }

    class Derived(b: Base4) : Base4 by b {
        override fun printMessage() {
            println("abc")
        }
    }

    val b = BaseImpl(6)
    Derived(b).printMessage()
    Derived(b).printMessageLine()
}

/*但请注意，以这种方式重写的成员不会在委托对象的成员中调用 ，委托对象的成员只能访问其自身对接口成员实现：*/
interface Base5 {
    val message: String
    fun print()

    fun message(): String
}

private fun foo2() {
    class BaseImpl : Base5 {
        override val message: String = "message of BaseImpl"
        override fun message(): String {
            return "messageMethod of BaseImpl"
        }

        override fun print() {
            println("filed message: $message , method message: ${message()}")
        }
    }

    class Derived(b: Base5) : Base5 by b {
        override val message: String = "message of Derived"

        override fun message(): String {
            return "messageMethod of Derived"
        }
    }

    val b = BaseImpl()
    val derived = Derived(b)
    derived.print()
    println(derived.message())
}

fun main() {
    foo2()
}